package socket;

import java.io.*;
import java.net.*;
import java.util.Vector;
import java.util.Iterator;



/**
 * 
 * pfister@lgi2p 07/11/28
 * 
 */
public class Server implements Protocol {

	private int id = 1;
	protected Vector<BaseClient> clients = new Vector<BaseClient>(); // Vector is
																	// synchronized
	private static Server instance;
	public final static boolean LOG = false;
	
	
	//Vector<ServerShape> shapes = new Vector<ServerShape>();

	public static void log(String mesg, boolean force) {
		if (LOG || force)
			System.out.println(" (server) " + mesg);
	}

	public void addClient(Socket sock, BaseClient client) throws IOException {
		broadCast(INCOMING + client.getName());
		notify(client);
		this.clients.add(client);
		new ServerClientThread(sock, client).start();
		//sendShapes(client);
	}

	public void removeClient(BaseClient client) throws IOException {
		broadCast(REMOVE + client.getName());
		this.clients.remove(client);
	}

	public static Server getInstance() {
		if (null == instance) {
			instance = new Server();
		}
		return instance;
	}

	
/*
	protected void addShape(String args) {
		ServerShape c = null;
		if (args.contains("Smily"))
			c = new Smily();
		else if (args.contains("Line"))
			c = new Line();
		else if (args.contains("Oval"))
			c = new Oval();
		else if (args.contains("Rectangle"))
			c = new Rectangle();
		else if (args.contains("SelectBox"))
			c = new SelectBox();
		else if (args.contains("Move"))
			c = new Move();
		if (c != null) {
			c.parse(args);
			shapes.add(c);
			log("create shape " + args, true);
		}
	}
	
	protected void broadcastShapes() throws IOException{
		for (ServerShape shape : shapes) {
			String mesg="SERVER "+SEND+D_CREATE_SHAPE+" "+shape.asString()+EOM;
			synchronized (clients) {
				for (Iterator<BaseClient> i = clients.iterator(); i.hasNext();)
					new PrintWriter(((i.next()).getSocket()).getOutputStream(),
							true).println(mesg);
			}
		}	
	}
	
	
	protected void sendShapes(BaseClient client) throws IOException{
		for (ServerShape shape : shapes) {
			String mesg="SERVER "+SEND+D_CREATE_SHAPE+" "+shape.asString()+EOM;
		    new PrintWriter(((client).getSocket()).getOutputStream(),
							true).println(mesg);
		}	
	}
	*/
	
	

	protected void parseCommand(String mesg){
		/*
		if (mesg.contains("p_create_shape")) {
			// UOTUV p_sendp_create_shape 39;127;256;329;39;256;notsel;Linep_eom
			String args = mesg.substring(
					mesg.indexOf(D_CREATE_SHAPE) + D_CREATE_SHAPE.length(),
					mesg.indexOf(EOM)).trim();
			addShape(args);
		}
		*/
	}
	
	public void broadCast(String mesg) throws IOException {
		log(BROADCAST + mesg, true);

	    parseCommand(mesg);

		synchronized (clients) {
			for (Iterator<BaseClient> i = clients.iterator(); i.hasNext();)
				new PrintWriter(((i.next()).getSocket()).getOutputStream(),
						true).println(mesg);
		}
	}

	public void notify(BaseClient client) throws IOException {
		String clts = "";
		synchronized (clients) {
			for (Iterator<BaseClient> i = clients.iterator(); i.hasNext();) {
				BaseClient c = i.next();
				clts += c.getName() + ";";
			}
			if (clients.size() == 0)
				clts = NOONE;
		}
		String mesg = CONNECTED + clts + WELCOME;
		new PrintWriter(client.getSocket().getOutputStream(), true)
				.println(mesg);
	}

	public void run() throws Exception {
		log(START, true);
		try {
			ServerSocket service = new ServerSocket(SERVERPORT);
			while (true) {
				log("waiting for connexion " + id, true);
				Socket socket = service.accept();
				log("connexion started " + id, true);
				BufferedReader socketReader = new BufferedReader(
						new InputStreamReader(socket.getInputStream()));
				String ligne = socketReader.readLine();
				if (ligne != null && ligne.startsWith(NEWCLIENT))
					addClient(socket, new BaseClient(id, socket, ligne
							.substring(NEWCLIENT.length()).trim()));
				else if (ligne == null)
					System.out.print("unknown connexion request syntax: "
							+ "null");
				else
					System.out.println("unknown connexion request syntax: "
							+ ligne);
				id++;
			}
		} catch (IOException e) {
			log("error " + e, true);
		}

	}

	public static void main(String[] args) throws Exception {
		Server monServeur = Server.getInstance();
		monServeur.run();
	}

}
